In [ ]:
from IPython.html import widgets
from IPython.display import display
from d3networkx import ForceDirectedGraph, EventfulGraph

Twitter Tweet Watcher

This example requires the Python "twitter" library to be installed (https://github.com/sixohsix/twitter). You can install Python twitter by running sudo pip install twitter from the terminal/commandline.


In [ ]:
from twitter import *
import time, datetime
import math

twitter_timestamp_format = "%a %b %d %X +0000 %Y"

In [ ]:
# Sign on to twitter.
auth = OAuth(
    consumer_key='iQvYfTfuD86fgVWGjPY0UA',
    consumer_secret='C3jjP6vzYzTYoHV4s5NYPGuRkpT5SulKRKTkRmYg',
    token='2218195843-cOPQa0D1Yk3JbvjvsCa0tIYzBOEWxINekmGcEql',
    token_secret='3BFncT1zAvJRN6rj8haCxveZVLZWZ23QeulxzByXWlfoO'
)
twitter = Twitter(auth = auth)
twitter_stream = TwitterStream(auth = auth, block = False)

In [ ]:
graph = EventfulGraph()
d3 = ForceDirectedGraph(graph)
d3.width = 600
d3.height = 400

stop_button = widgets.Button(description="Stop")
        
# Only listen to tweets while they are available and the user
# doesn't want to stop.
stop_listening = [False]
def handle_stop(sender):
    stop_listening[0] = True
    print("Service stopped")
stop_button.on_click(handle_stop)

def watch_tweets(screen_name=None):
    display(d3)
    display(stop_button)
    graph.node.clear()
    graph.adj.clear()
    start_timestamp = None
    stop_button._dom_classes = ['btn', 'btn-danger']
    
    # Get Barack's tweets
    tweets = twitter.statuses.user_timeline(screen_name=screen_name)
    user_id = twitter.users.lookup(screen_name=screen_name)[0]['id']
    
    # Determine the maximum number of retweets.
    max_retweets = 0.0
    for tweet in tweets:
        max_retweets = float(max(tweet['retweet_count'], max_retweets))
        
    
    def plot_tweet(tweet, parent=None, elapsed_seconds=1.0, color="gold"):
        new_id = tweet['id']
        graph.add_node(
            new_id, 
            r=max(float(tweet['retweet_count']) / max_retweets * 30.0, 3.0),
            charge=-60,
            fill = color,
        )
        
        if parent is not None:
            parent_radius = max(float(parent['retweet_count']) / max_retweets * 30.0, 3.0)
            graph.node[parent['id']]['r'] = parent_radius
            
            graph.add_edge(new_id, parent['id'], distance=math.log(elapsed_seconds) * 9.0 + parent_radius)
            graph.node[new_id]['fill'] = 'red'
            
        
    # Plot each tweet.
    for tweet in tweets:
        plot_tweet(tweet)
    
    kernel=get_ipython().kernel
    iterator = twitter_stream.statuses.filter(follow=user_id)
    
    while not stop_listening[0]:
        kernel.do_one_iteration()
        
        for tweet in iterator:
            kernel.do_one_iteration()
            if stop_listening[0] or tweet is None:
                break
            else:
                if 'retweeted_status' in tweet:
                    original_tweet = tweet['retweeted_status']
                    if original_tweet['id'] in graph.node:
                        tweet_timestamp = datetime.datetime.strptime(tweet['created_at'], twitter_timestamp_format) 
                        if start_timestamp is None:
                            start_timestamp = tweet_timestamp
                        elapsed_seconds = max((tweet_timestamp - start_timestamp).total_seconds(),1.0)
                        
                        plot_tweet(tweet, parent=original_tweet, elapsed_seconds=elapsed_seconds)
                elif 'id' in tweet:
                    plot_tweet(tweet, color='lime')

In [ ]:
watch_tweets(screen_name="justinbieber")